﻿using Engine.Graphics;
using Engine.Graphics.Shaders;
using Engine.Graphics.Shaders.Wr2Shaders;
using System.Collections.Generic;
using WorldRacing2.Material;
using WorldRacing2.Shaders;

namespace WorldRacing2
{
    public class Wr2ShaderArray : IShaderArray
    {
        #region Internal Properties

        internal EnumGlobalShader GlobalShader { get; set; }

        #endregion Internal Properties

        #region Private Fields

        private Engine.Engine engine;

        private Material000 material000;
        private Material016 material016;
        private Material032 material032;
        private Material048 material048;
        private Material064 material064;
        private Material080 material080;
        private Material096 material096;
        private Material112 material112;
        private Material128 material128;
        private Material144 material144;
        private Material160 material160;
        private Material176 material176;
        private Material192 material192;
        private Material208 material208;
        private Material224 material224;
        private Material240 material240;
        private List<ISetShaderValues> registeredShaders;
        private ShaderManager shaderManager;
        private string shaderpath;
        private VertexColorShader vertexColorShader;

        #endregion Private Fields

        #region Public Constructors

        public Wr2ShaderArray(Engine.Engine engine, string shaderpath, ShaderManager shaderManager)
        {
            Engine.Helpers.LogWriter.Write(0, "Create World Racing 2 Shaders");
            this.engine = engine;
            this.shaderManager = shaderManager;
            this.shaderpath = shaderpath += "\\WorldRacing2\\";
            this.registeredShaders = new List<ISetShaderValues>();
            LoadShaders(this.shaderpath, engine, this.shaderManager);
        }

        #endregion Public Constructors

        #region Public Methods

        public void Dispose()
        {
            foreach (var item in this.registeredShaders)
            {
                item.Dispose();
            }

            this.registeredShaders.Clear();
        }

        public List<ISetShaderValues> GetRegisteredShaders()
        {
            return this.registeredShaders;
        }

        public void ReloadShaders(ShaderManager shaderManager)
        {
            Dispose();
            LoadShaders(this.shaderpath, this.engine, this.shaderManager);
        }

        public ShaderBase SetEffectValues(int materialID, MaterialManager materialManager)
        {
            switch (GameDll.shaderArray.GlobalShader)
            {
                case EnumGlobalShader.Material:

                    Wr2Material material = (Wr2Material)materialManager.GetMaterialForGame(materialID);

                    switch ((EnumMappingMode)material.MappingMode)
                    {
                        case EnumMappingMode.material00:
                        case EnumMappingMode.material02:
                            this.material000.SetProperties(materialID, materialManager);
                            return this.material000;

                        case EnumMappingMode.material16:
                            this.material016.SetProperties(materialID, materialManager);
                            return this.material016;

                        case EnumMappingMode.material32:
                            this.material032.SetProperties(materialID, materialManager);
                            return this.material032;

                        case EnumMappingMode.material48:
                            this.material048.SetProperties(materialID, materialManager);
                            return this.material048;

                        case EnumMappingMode.material64:
                            this.material064.SetProperties(materialID, materialManager);
                            return this.material064;

                        case EnumMappingMode.material80:
                            this.material080.SetProperties(materialID, materialManager);
                            return this.material080;

                        case EnumMappingMode.material96:
                            this.material096.SetProperties(materialID, materialManager);
                            return this.material096;

                        case EnumMappingMode.material112:
                            this.material112.SetProperties(materialID, materialManager);
                            return this.material112;

                        case EnumMappingMode.material128:
                            this.material128.SetProperties(materialID, materialManager);
                            return this.material128;

                        case EnumMappingMode.material144:
                            this.material144.SetProperties(materialID, materialManager);
                            return this.material144;

                        case EnumMappingMode.material160:
                            this.material160.SetProperties(materialID, materialManager);
                            return this.material160;

                        case EnumMappingMode.material176:
                            this.material176.SetProperties(materialID, materialManager);
                            return this.material176;

                        case EnumMappingMode.material192:
                            this.material192.SetProperties(materialID, materialManager);
                            return this.material192;

                        case EnumMappingMode.material208:
                            this.material208.SetProperties(materialID, materialManager);
                            return this.material208;

                        case EnumMappingMode.material224:
                            this.material224.SetProperties(materialID, materialManager);
                            return this.material224;

                        case EnumMappingMode.material240:
                            this.material240.SetProperties(materialID, materialManager);
                            return this.material240;

                        default:
                            // throw new Exception("Set effect value is not implemented");
                            this.material000.SetProperties(materialID, materialManager);
                            return this.material000;
                    }

                case EnumGlobalShader.VertexColor:
                    this.vertexColorShader.SetProperties(materialID, materialManager);
                    return this.vertexColorShader;

                default:
                    throw new System.Exception("No globla shader set in World racing shaderarray!");
            }
        }

        #endregion Public Methods

        #region Private Methods

        private void LoadShaders(string shaderPath, Engine.Engine engine, ShaderManager shaderManger)
        {
            var device = engine.Grafic.Device;
            //Load
            this.material000 = new Material000(device, shaderPath, shaderManger);
            this.material016 = new Material016(device, shaderPath, shaderManger);
            this.material032 = new Material032(device, shaderPath, shaderManger);
            this.material048 = new Material048(device, shaderPath, shaderManger);
            this.material064 = new Material064(device, shaderPath, shaderManger);
            this.material080 = new Material080(device, shaderPath, shaderManger);
            this.material096 = new Material096(device, shaderPath, shaderManger);
            this.material112 = new Material112(device, shaderPath, shaderManger);
            this.material128 = new Material128(device, shaderPath, shaderManger);
            this.material144 = new Material144(device, shaderPath, shaderManger);
            this.material160 = new Material160(device, shaderPath, shaderManger);
            this.material176 = new Material176(device, shaderPath, shaderManger);
            this.material192 = new Material192(device, shaderPath, shaderManger);
            this.material208 = new Material208(device, shaderPath, shaderManger);
            this.material224 = new Material224(device, shaderPath, shaderManger);
            this.material240 = new Material240(device, shaderPath, shaderManger);

            this.vertexColorShader = new VertexColorShader(device, shaderPath, shaderManger);

            this.registeredShaders.Clear();
            this.registeredShaders.Add(this.material000);
            this.registeredShaders.Add(this.material016);
            this.registeredShaders.Add(this.material032);
            this.registeredShaders.Add(this.material048);
            this.registeredShaders.Add(this.material064);
            this.registeredShaders.Add(this.material080);
            this.registeredShaders.Add(this.material096);
            this.registeredShaders.Add(this.material112);
            this.registeredShaders.Add(this.material128);
            this.registeredShaders.Add(this.material144);
            this.registeredShaders.Add(this.material160);
            this.registeredShaders.Add(this.material176);
            this.registeredShaders.Add(this.material192);
            this.registeredShaders.Add(this.material208);
            this.registeredShaders.Add(this.material224);
            this.registeredShaders.Add(this.material240);
            this.registeredShaders.Add(this.vertexColorShader);
        }

        #endregion Private Methods
    }
}